package com.sunday.minio.utils;

import com.sunday.minio.constants.MinioConstants;
import com.sunday.minio.entity.BaseResult;
import lombok.extern.slf4j.Slf4j;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

/**
 * MinIO工具类
 *
 * @author zsy
 * @since 2023/10/16
 */
@Slf4j
public class MinioUtils {

    /**
     * 生成minio中path
     *
     * @param first 路径字符串或路径字符串的初始部分
     * @return {@link String} 2024/01/25(当前时间) + "/" + 文件名uuid(name) + "." + 文件类型(type)
     */
    public static String objectName(String first) {
        return objectName(Paths.get(first));
    }

    /**
     * 生成minio中path
     * 例如：文件上传路径 D:\app\minIO\447680d47859c66d417a7bbaaa70b21c.jpeg -> minio 表示形式 2024/01/25/331f6f9f0818db547de841ec6e629f43.jpeg
     *
     * @param path 通过解析path，获取文件类型，文件名以uuid的形式保存，并添加路径以日期前缀
     * @return {@link String} 2024/01/25(当前时间) + "/" + 文件名uuid(name) + "." + 文件类型(type)
     */
    public static String objectName(Path path) {
        String filename = path.getFileName().toString();
        int dot = filename.lastIndexOf(MinioConstants.DOT);
        assert (dot > 0 && dot < filename.length() - 1) : "file type cannot be resolved!";
        String type = filename.substring(dot + 1);
        return objectName(get32UUID(), type);
    }

    /**
     * 生成minio中path
     *
     * @param name 保存到minIO的文件名
     * @param type 文件类型
     * @return {@link String} 2024/01/25(当前时间) + "/" + 文件名uuid(name) + "." + 文件类型(type)
     */
    public static String objectName(String name, String type) {
        return formattedNow() + MinioConstants.SLASH + name + MinioConstants.DOT + type;
    }

    /**
     * 获取uuid
     * 使用ThreadLocalRandom获取UUID获取更优的效果 去掉"-"
     *
     * @return {@link String}
     */
    public static String get32UUID() {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        return new UUID(random.nextLong(), random.nextLong()).toString().replace(MinioConstants.DASH, MinioConstants.EMPTY);
    }

    /**
     * 时间格式化
     *
     * @return {@link String}
     */
    public static String formattedNow() {
        return LocalDate.now().format(MinioConstants.DATE_FORMATTER);
    }

    /**
     * 通过文件名获取内容类型
     *
     * @param filename
     * @return {@link String}
     */
    public static String contentType(String filename) {
        return contentType(Paths.get(filename));
    }

    /**
     * 通过文件路径获取内容类型
     *
     * @param path
     * @return {@link String}
     */
    public static String contentType(Path path) {
        try {
            return Files.probeContentType(path);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 格式化获得目标便于数据库存储
     * 例如 ：
     * 原始信息
     * bucket = file
     * object = 2024/01/25/09b8e619734981ea5134636b91dc72c3.jpeg
     * 变换后
     * file@2024/01/25/09b8e619734981ea5134636b91dc72c3.jpeg
     *
     * @param result
     * @return {@link String}
     */
    public static String format(BaseResult result) {
        return result.getBucket() + MinioConstants.AT + result.getObject();
    }

    /**
     * 解析目标
     *
     * @param target
     * @return {@link BaseResult}
     */
    public static BaseResult parse(String target) {
        String[] idents = target.split(MinioConstants.AT);
        assert (idents != null && idents.length == 2) : "target format invalid!";
        return BaseResult.of(idents[0], idents[1]);
    }

}
